
#include "shading.fx"
#include "samplers.fx"
#include "fog.fx"

struct VS_IN
{
	float3 position : POSITION;
	float3 normal	: NORMAL;
	float3 tangent : TANGENT;
	float2 tex		: TEX_COORDS;
};


struct VS_OUT
{
	float4 position : SV_POSITION;
	float4 ws_pos	: WS_POSITION;
	float3 normal	: NORMAL;
	float2 tex		: TEX_COORDS;
};



struct FLAT_VS_OUT
{
	float4 position					: SV_POSITION;
	float4 ws_pos					: WS_POSITION;
	nointerpolation float3 normal	: NORMAL;
	float2 tex						: TEX_COORDS;
};



float4x4 m_World;
float4x4 m_WorldViewProj;



VS_OUT VS(VS_IN vin)
{
	VS_OUT vout;

	vout.position = mul(float4(vin.position, 1.0f), m_WorldViewProj);
	vout.ws_pos = mul(float4(vin.position, 1.0f), m_World);
	vout.normal = mul(float4(vin.normal, 0.0f), m_World).xyz;
	vout.tex =	  vin.tex;

	return vout;
}







SamplerState s_volume
{
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Clamp;
    AddressV = Clamp;
    AddressW = Clamp;
};

float4 PS(VS_OUT pin, uniform bool bTextured, uniform bool bLit) : SV_TARGET
{
	float4 color = float4(0.0f, 0.0f, 0.0f, 1.0f);
	
	if (bLit)
		color = float4(shade(pin.ws_pos.xyz, normalize(pin.normal), 0), 1.0f);
			
	float4 ambient = float4(0.1f, 0.1f, 0.1f, 0.0f);

	if (mat_params.vIsTextured.x && bTextured)
	{
		float4 tex_diff = tex_diffuse.Sample(s_linear, pin.tex);
		color *= tex_diff;
		ambient *= tex_diff;
	}

	// set alpha in w
	color = float4(color.xyz, mat_params.diffuse.w);

	color += ambient;
	color = computeFog(color, pin.ws_pos.xyz, pin.ws_pos.y, 3.0f, pEye);

	return color;
}


RasterizerState rs_state
{
	CullMode = Back;
};



RasterizerState rs_Wireframe
{
	CullMode = Back;
	FillMode = Wireframe;
};



DepthStencilState EnableDepth
{
    DepthEnable = true;
};


technique10 Tree 
{
    pass P0 
	{
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
		SetGeometryShader( NULL);
        SetPixelShader( CompileShader( ps_4_0, PS(true, true) ) );
		
		SetBlendState(0, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xffffffff);
		SetRasterizerState(rs_state);
		SetDepthStencilState(0, 0);

	}
}


////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

FLAT_VS_OUT Flat_VS(VS_IN vin)
{
	FLAT_VS_OUT vout;

	vout.position = mul(float4(vin.position, 1.0f), m_WorldViewProj);
	vout.ws_pos = mul(float4(vin.position, 1.0f), m_World);
	vout.normal = mul(float4(vin.normal, 0.0f), m_World).xyz;
	vout.tex =	  vin.tex;

	return vout;
}


float4 Flat_PS(FLAT_VS_OUT pin, uniform bool bTextured, uniform bool bLit) : SV_TARGET
{
	float4 color = float4(0.0f, 0.0f, 0.0f, 1.0f);
	
	if (bLit)
		color = float4(shade(pin.ws_pos.xyz, normalize(pin.normal), 0), 1.0f);
			
	float4 ambient = float4(0.1f, 0.1f, 0.1f, 0.0f);

	if (mat_params.vIsTextured.x && bTextured)
	{
		float4 tex_diff = tex_diffuse.Sample(s_linear, pin.tex);
		color *= tex_diff;
		ambient *= tex_diff;
	}

	// set alpha in w
	color = float4(color.xyz, mat_params.diffuse.w);

	color += ambient;
	color = computeFog(color, pin.ws_pos.xyz, pin.ws_pos.y, 3.0f, pEye);

	return color;
}

Texture2D tex_heightmap;

VS_OUT DM_VS(VS_IN vin)
{
	VS_OUT vout;

	
	// pick values from heightmaps
	float h = tex_heightmap.SampleLevel(s_linear, vin.tex, 0).r;

	// displace vertex pos
	float3 displaced_pos = vin.position + vin.normal * h * 0.2f;

	// rest of vsout values
	vout.position = mul(float4(displaced_pos, 1.0f), m_WorldViewProj);
	vout.ws_pos = mul(float4(displaced_pos, 1.0f), m_World);
	vout.normal = mul(float4(vin.normal, 0.0f), m_World).xyz;
	vout.tex = vin.tex;

	return vout;
}


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


technique10 Tree_NonTexturedNonLitWireframe
{
	pass P0
	{
		SetVertexShader( CompileShader( vs_4_0,   VS()  ) );
		SetGeometryShader( NULL);
		SetPixelShader( CompileShader( ps_4_0,    PS(false, false) ) );
		
		SetBlendState(0, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xffffffff);
		SetRasterizerState(rs_Wireframe);
		SetDepthStencilState(0, 0);
	}
}


technique10 Tree_NonTexturedFlatShaded
{
	pass P0
	{
		SetVertexShader( CompileShader( vs_4_0,  Flat_VS()   ) );
		SetGeometryShader( NULL);
		SetPixelShader( CompileShader( ps_4_0,   Flat_PS(false, true)   ) );
		
		SetBlendState(0, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xffffffff);
		SetRasterizerState(0);
		SetDepthStencilState(0, 0);
	}
}

technique10 Tree_NonTexturedSmoothShaded
{
	pass P0
	{
		SetVertexShader( CompileShader( vs_4_0,  VS()   ) );
		SetGeometryShader( NULL);
		SetPixelShader( CompileShader( ps_4_0,   PS(false, true) ) );
		
		SetBlendState(0, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xffffffff);
		SetRasterizerState(0);
		SetDepthStencilState(0, 0);
	}
}

technique10 Tree_DisplacementMapping
{
	pass P0
	{
		SetVertexShader( CompileShader( vs_4_0,  DM_VS()   ) );
		SetGeometryShader( NULL);
		SetPixelShader( CompileShader( ps_4_0,   PS(true, true)   ) );
			
		SetBlendState(0, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xffffffff);
		SetRasterizerState(0);
		SetDepthStencilState(0, 0);
	}
}

